From 4e6c3bd10afcd5232328147830c691149f925093 Mon Sep 17 00:00:00 2001 From: Yehuda Katz Date: Fri, 18 Jul 2014 04:49:34 -0700 Subject: [PATCH] Improve error message on failed compile --- src/cargo/lib.rs | 4 +++- src/cargo/ops/cargo_rustc/mod.rs | 8 +++++--- src/cargo/util/errors.rs | 29 ++++++++++++++++++++++++----- src/cargo/util/mod.rs | 2 +- tests/support/mod.rs | 4 ++-- tests/test_cargo_compile.rs | 10 +++------- 6 files changed, 38 insertions(+), 19 deletions(-) diff --git a/src/cargo/lib.rs b/src/cargo/lib.rs index 0b6126804..e7b7c4914 100644 --- a/src/cargo/lib.rs +++ b/src/cargo/lib.rs @@ -209,7 +209,9 @@ pub fn handle_error(err: CliError, shell: &mut MultiShell) { } let _ = shell.verbose(|shell| { - let _ = handle_cause(error, shell); + error.cause().map(|err| { + let _ = handle_cause(err, shell); + }); Ok(()) }); diff --git a/src/cargo/ops/cargo_rustc/mod.rs b/src/cargo/ops/cargo_rustc/mod.rs index df4115539..16c0976f5 100644 --- a/src/cargo/ops/cargo_rustc/mod.rs +++ b/src/cargo/ops/cargo_rustc/mod.rs @@ -3,7 +3,7 @@ use std::collections::HashSet; use core::{Package, PackageId, PackageSet, Target, Resolve}; use util; -use util::{CargoResult, ProcessBuilder, CargoError, human}; +use util::{CargoResult, ProcessBuilder, CargoError, ChainError, human, caused_human}; use util::{Config, Freshness, internal, ChainError}; use self::job::Job; @@ -187,14 +187,16 @@ fn rustc(package: &Package, target: &Target, }); rustcs.move_iter().map(|rustc| { + let name = package.get_name().to_string(); + Job::new(proc() { if primary { log!(5, "executing primary"); - try!(rustc.exec().map_err(|err| human(err.to_string()))) + try!(rustc.exec().chain_error(|| human(format!("Could not compile `{}`.", name)))) } else { log!(5, "executing deps"); try!(rustc.exec_with_output().and(Ok(())).map_err(|err| { - human(err.to_string()) + caused_human(format!("Could not compile `{}`.\n{}", name, err.output().unwrap()), err) })) } Ok(Vec::new()) diff --git a/src/cargo/util/errors.rs b/src/cargo/util/errors.rs index 902f8cd37..51aff2799 100644 --- a/src/cargo/util/errors.rs +++ b/src/cargo/util/errors.rs @@ -156,24 +156,34 @@ impl Show for ProcessError { None => "never executed".to_string() }; try!(write!(f, "{} (status={})", self.msg, exit)); + self.output().map(|out| { let _ = write!(f, "{}", out); }); + Ok(()) + } +} + +impl ProcessError { + pub fn output(&self) -> Option { match self.output { Some(ref out) => { + let mut string = String::new(); match str::from_utf8(out.output.as_slice()) { Some(s) if s.trim().len() > 0 => { - try!(write!(f, "\n--- stdout\n{}", s)); + string.push_str("\n--- stdout\n"); + string.push_str(s); } Some(..) | None => {} } match str::from_utf8(out.error.as_slice()) { Some(s) if s.trim().len() > 0 => { - try!(write!(f, "\n--- stderr\n{}", s)); + string.push_str("\n--- stderr\n"); + string.push_str(s); } Some(..) | None => {} } - } - None => {} + Some(string) + }, + None => None } - Ok(()) } } @@ -311,3 +321,12 @@ pub fn human(error: S) -> Box { is_human: true } as Box } + +pub fn caused_human(error: S, cause: E) -> Box { + box ConcreteCargoError { + description: error.to_string(), + detail: None, + cause: Some(cause.box_error()), + is_human: true + } as Box +} diff --git a/src/cargo/util/mod.rs b/src/cargo/util/mod.rs index 71240d006..017b23f2d 100644 --- a/src/cargo/util/mod.rs +++ b/src/cargo/util/mod.rs @@ -3,7 +3,7 @@ pub use self::process_builder::{process, ProcessBuilder}; pub use self::result::{Wrap, Require}; pub use self::errors::{CargoResult, CargoError, BoxError, ChainError, CliResult}; pub use self::errors::{CliError, FromError, ProcessError}; -pub use self::errors::{process_error, internal_error, internal, human}; +pub use self::errors::{process_error, internal_error, internal, human, caused_human}; pub use self::paths::realpath; pub use self::hex::{to_hex, short_hash}; pub use self::pool::TaskPool; diff --git a/tests/support/mod.rs b/tests/support/mod.rs index ca94f5088..25cf7203e 100644 --- a/tests/support/mod.rs +++ b/tests/support/mod.rs @@ -270,8 +270,8 @@ impl Execs { actual.status.matches_exit_status(code), format!("exited with {}\n--- stdout\n{}\n--- stderr\n{}", actual.status, - str::from_utf8(actual.output.as_slice()), - str::from_utf8(actual.error.as_slice()))) + String::from_utf8_lossy(actual.output.as_slice()), + String::from_utf8_lossy(actual.error.as_slice()))) } } } diff --git a/tests/test_cargo_compile.rs b/tests/test_cargo_compile.rs index 39544b371..5a5529bc3 100644 --- a/tests/test_cargo_compile.rs +++ b/tests/test_cargo_compile.rs @@ -83,8 +83,6 @@ test!(cargo_compile_with_invalid_code { .file("Cargo.toml", basic_bin_manifest("foo").as_slice()) .file("src/foo.rs", "invalid rust code!"); - let target = realpath(&p.root().join("target")).assert(); - assert_that(p.cargo_process("cargo-build"), execs() .with_status(101) @@ -92,11 +90,9 @@ test!(cargo_compile_with_invalid_code { {filename}:1:1: 1:8 error: expected item but found `invalid` {filename}:1 invalid rust code! ^~~~~~~ -Could not execute process \ -`rustc {filename} --crate-name foo --crate-type bin --out-dir {} -L {} -L {}` (status=101)\n", - target.display(), - target.display(), - target.join("deps").display(), +Could not compile `foo`. + +To learn more, run the command again with --verbose.\n", filename = format!("src{}foo.rs", path::SEP)).as_slice())); }) -- 2.30.2